package org.xm.sk.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.xm.sk.filter.auth.UserAuthEntryPoint;
import org.xm.sk.filter.auth.UserAuthTokenFilter;
import org.xm.sk.service.security.UserPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserAuthEntryPoint authEntryPoint;

    @Autowired
    private UserDetailsService userDetailsService;

    @Value("${jwt.route.authentication.path.cl}")
    private String cl_auth;

    @Bean
    public UserAuthTokenFilter authTokenFilterBean()
            throws Exception {
        return new UserAuthTokenFilter();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new UserPasswordEncoder();
    }
    
    @Bean
    public AuthenticationManager getAuthenticationManager() throws Exception {
        return authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.headers().frameOptions().sameOrigin().disable()// disable X-Frame-Options
                .authorizeRequests().antMatchers("/", "/" + cl_auth + "/**")
                .permitAll().anyRequest().fullyAuthenticated()// 其他url需要鉴权
                .and().exceptionHandling()
                .authenticationEntryPoint(authEntryPoint).and()
                // 基于Token 不需要Session
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().logout().deleteCookies("JSESSIONID")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login").and().csrf().disable().cors().and() // disable csrf
                .sessionManagement().maximumSessions(1);

        // 添加JWT filter
        http.addFilterBefore(authTokenFilterBean(),
                UsernamePasswordAuthenticationFilter.class);

        // 禁用缓存
        http.headers().cacheControl();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.userDetailsService(this.userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/images/f/**",
                "/swagger-resources/**", "/configuration/security", "/orders/pay/notify",
                "/swagger-ui.html", "/webjars/**", "/docs**", "/index**", "/test**", "/css/**","/fonts/**","/img/**","/locales/**","/utils/**","/vendor/**", "/api_data**", "/api_project**", "/main**");
    }

}
